package com.example.springbootthreaddemo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.juli.logging.Log;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * @Author: jixiaotian.ch@qq.com
 * @Date : 2020/9/2
 */

@Log4j2
@RestController
public class MingDa {


    public static String appId = "9095d7c04a16442886598b1ec45250cd";
    public static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClbFeDw49rCEVWYttWQf9grQMFrMk3I4GAlECMJpmFCBpJjnVr/xBe3V7T0e29HARk136jGAk4II+jwFXIrsSr5UAwdbUNxIyZLPGOVyAsNz156om5K5JPmeKt85+5X8wKrBuuxsvHWG74DX9Ce4GaoSyCY7lFs1FS7Uj/jhVUiQIDAQAB";
    public static String channelCode = "mingda_jingji";
    public static String loginUrl = "http://apitst.woyunsoft.com/openapi/channel/auth/loginDirectUrl";
    public static String registUrl = "http://bmptst.aoyunsoft.com/";


    private static final int MAX_ENCRYPT_BLOCK = 117;

    public static String encryptByPublicKey(String data, String key) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(key);
        byte[] dataBytes = data.getBytes("UTF-8");
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = dataBytes.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return Base64.encodeBase64String(encryptedData);
    }
    @PostMapping("/mingda/login")
    public static JSONObject login(String mobile,String select) throws Exception {
        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("appId",appId);
        dataMap.put("channelCode",channelCode);
        dataMap.put("mobile",mobile);
        dataMap.put("select",select);
        dataMap.put("agentCode","123456");
        dataMap.put("timestamp",String.valueOf(System.currentTimeMillis()/1000));
        return post(dataMap,loginUrl);
    }

    @PostMapping("/mingda/register")
    public static JSONObject register(String id,String name, String mobile, String partnerId, String email) throws Exception {
        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("id",id);
        dataMap.put("name",name);
        dataMap.put("mobile",mobile);
        dataMap.put("channelCode",channelCode);
        dataMap.put("partnerId",partnerId);
        dataMap.put("email",email);
        dataMap.put("timestamp",String.valueOf(System.currentTimeMillis()/1000));
        return post(dataMap,registUrl);

    }

    @lombok.SneakyThrows
    public static JSONObject post(Map<String, String> params,String url){

        StringBuffer data = new StringBuffer();
        params.forEach((key,value)->{
            data.append(key)
                    .append("=")
                    .append(value)
                    .append("&");
        });
        data.delete(data.length()-1,data.length());
        String signature = encryptByPublicKey(data.toString(), publicKey);

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost method = new HttpPost(url);

        List<NameValuePair> paramList = new ArrayList<>();
        NameValuePair nameValuePair = new BasicNameValuePair("appId", appId);
        paramList.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("signature", signature);
        paramList.add(nameValuePair);

        JSONObject json = new JSONObject();
        json.put("appId",appId);
        json.put("signature",signature);
        StringEntity s = new StringEntity(json.toString());
        s.setContentEncoding("UTF-8");
        s.setContentType("application/json");//发送json数据需要设置contentType
        method.setEntity(s);
        method.setHeader("appId",appId);
        method.setHeader("signature",signature);

        String resp = "";
        CloseableHttpResponse response = null;
        try {
            response = client.execute(method);
            HttpEntity entity = response.getEntity();
            if(entity!=null) {
                resp = EntityUtils.toString(entity,"UTF-8");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(response!=null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return JSONObject.parseObject(resp);
    }

}
